home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
mg2a_src.zip
/
TTY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-16
|
7KB
|
340 lines
/*
* Mg 2b (turboc 1.5/MSC 1.5)
* IBM-PC and compatible BIOS based display driver.
* - this will tend to be a bit slower than a driver that
* writes directly to the memory mapped screen, but with
* the large # of display adapters floating around, I'd
* rather let the bios do the work.
*
* I DO recommend FANSI-CONSOLE which significantly speeds
* up display bios calls, however.
*/
#include "def.h"
#include <dos.h>
#define BEL 0x07 /* BEL character. */
extern int ttrow;
extern int ttcol;
extern int tttop;
extern int ttbot;
extern int tthue;
static int biocol = 0;
int tceeol = 2; /* Costs are set later */
int tcinsl = 5;
int tcdell = 5;
static int insdel = TRUE; /* Do we have both insert & delete line? */
static int rendition =0x07;
int ttputc();
/*
* Initialize the terminal when the editor
* gets started up.
*/
ttinit() {
}
/*
* Clean up the terminal, in anticipation of
* a return to the command interpreter.
*/
tttidy() {
}
/*
* Move the cursor to the specified
* origin 0 row and column position.
*/
ttmove(row, col) {
ttcol = col;
ttrow = row;
_move(row, col);
}
_move(row, col) {
union REGS rg;
biocol = col;
rg.h.ah = 2; /* set cursor position function code */
rg.h.dl = col;
rg.h.dh = row;
rg.h.bh = 0; /* set screen page number */
int86(0x10, &rg, &rg);
}
/*
* Erase to end of line.
*/
tteeol() {
union REGS rg;
rg.h.ah = 9; /* write character/rendition */
rg.h.bh = 0;
rg.x.cx = ncol-biocol;
rg.h.al = ' ';
rg.h.bl = rendition;
int86(0x10, &rg, &rg);
}
/*
* Erase to end of page.
*/
tteeop() {
ttdell(ttrow, nrow, nrow - ttrow);
}
/*
* Make a noise.
*/
ttbeep() {
union REGS rg;
rg.h.ah = 14; /* write tty */
rg.h.al = BEL;
int86(0x10, &rg, &rg);
}
/*
* Insert nchunk blank line(s) onto the
* screen, scrolling the last line on the
* screen off the bottom.
*/
ttinsl(row, bot, nchunk) {
union REGS rg;
if (row == bot) { /* Case of one line insert is */
ttmove(row, 0); /* special */
tteeol();
return;
}
rg.h.ah = 7; /* scroll down */
rg.h.bh = 0x07;
rg.h.al = nchunk;
rg.h.ch = row;
rg.h.cl = 0;
rg.h.dh = bot;
rg.h.dl = ncol - 1;
int86(0x10, &rg, &rg);
}
/*
* Delete nchunk line(s) from "row", replacing the
* bottom line on the screen with a blank line.
*/
ttdell(row, bot, nchunk)
{
union REGS rg;
if (row == bot) { /* One line special case */
ttmove(row, 0);
tteeol();
return;
}
rg.h.ah = 6; /* scroll up */
rg.h.bh = 0x07;
rg.h.al = nchunk;
rg.h.ch = row;
rg.h.cl = 0;
rg.h.dh = bot;
rg.h.dl = ncol - 1;
int86(0x10, &rg, &rg);
}
/*
* Switch to full screen scroll. This is
* used by "spawn.c" just before is suspends the
* editor, and by "display.c" when it is getting ready
* to exit.
*/
ttnowindow()
{
}
/*
* Set the current writing color to the
* specified color. Watch for color changes that are
* not going to do anything (the color is already right)
* and don't send anything to the display.
* The rainbow version does this in putline.s on a
* line by line basis, so don't bother sending
* out the color shift.
*/
ttcolor(color) register int color; {
if (color != tthue) {
if (color == CTEXT) { /* Normal video. */
rendition = 0x07;
} else if (color == CMODE) { /* Reverse video. */
rendition = 0x70;
}
tthue = color; /* Save the color. */
}
}
/*
* This routine is called by the
* "refresh the screen" command to try and resize
* the display. The new size, which must be deadstopped
* to not exceed the NROW and NCOL limits, it stored
* back into "nrow" and "ncol". Display can always deal
* with a screen NROW by NCOL. Look in "window.c" to
* see how the caller deals with a change.
*/
ttresize() {
setttysize();
}
/* calculate the cost of doing string s */
charcost (s) char *s; {
return strlen(s);
}
ttputc(c)
unsigned char c;
{
union REGS rg;
if (c == '\b') {
if (biocol-1 > 0) {
_move(ttrow, biocol-1);
}
return;
}
else if (c == '\r') {
_move(ttrow, 0);
return;
}
rg.h.ah = 9; /* write character/rendition */
rg.h.bh = 0;
rg.x.cx = 1;
rg.h.al = c;
rg.h.bl = rendition;
int86(0x10, &rg, &rg);
if (biocol+1 >= ncol)
_move(ttrow + 1, 0);
else
_move(ttrow, biocol + 1);
}
struct nap
{
long napvalue;
long basetime;
};
ttwait()
{
struct nap timer;
napstart(200, &timer);
while (napchk(&timer) == 0)
if (typeahead())
return 0;
return 1;
}
/***************************/
/* MSDOS time functions */
/***************************/
/* Apparantly Turbo C has a sleep library routine; MSC doesn't -jbs */
#define gettime(_a) ((((long)(_a.x.cx)) << 16)+_a.x.dx)
#ifdef MSC
sleep(amount)
{
while (amount--)
nap(100);
}
#endif
/* nap in units of 100ths of seconds via busy loops. */
nap(amount)
{
struct nap tim;
napstart(amount, &tim);
while(napchk(&tim) == 0)
;
}
napstart(amount,sav)
int amount;
register struct nap *sav;
{
union REGS inregs, outregs;
int hunds, secs;
inregs.h.ah = 0x2c; /* get time */
int86(0x21, &inregs, &outregs);
/* glitch in hardware RTC (time warp) makes this necessary */
inregs = outregs;
inregs.h.dl = 0; /* seconds counter may be slow to increment */
if (inregs.h.dh > 0)
--inregs.h.dh; /* paranoia */
if (inregs.h.cl > 0)
--inregs.h.cl; /* more paranoia */
/* end of glitch handling */
sav->basetime = gettime(inregs); /* in case of wraparound */
/* convert hundredths of seconds to future time structure */
secs = outregs.h.dh;
hunds = outregs.h.dl + amount;
while (hunds >= 100) {
hunds -= 100;
++secs;
}
outregs.h.dl = hunds;
while (secs >= 60) {
secs -= 60;
++outregs.h.cl; /* increment minutes */
}
outregs.h.dh = secs;
/* check for minute and hour wraparound */
if (outregs.h.cl >= 60)
{
outregs.h.cl -= 60;
++outregs.h.ch; /* increment hours */
}
if (outregs.h.ch >= 24)
{
outregs.h.ch -= 24;
}
sav->napvalue = gettime(outregs);
}
napchk(sav)
register struct nap *sav;
{
union REGS inregs, outregs;
long current;
inregs.h.ah = 0x2c; /* get time */
int86(0x21, &inregs, &outregs);
current = gettime(outregs);
if(sav->napvalue > sav->basetime)
{
if (current >= sav->napvalue || current < sav->basetime)
return 1;
}
else if (current >= sav->napvalue && current < sav->basetime)
return 1;
return 0;
}